package com.rzt.cft.api.controller.uc;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rzt.cft.api.controller.BaseController;
import com.rzt.cft.api.fiter.CustomAuthorize;
import com.rzt.cft.constant.ServiceStatus;
import com.rzt.cft.constant.StatusConstant;
import com.rzt.cft.constant.TypeConstant;
import com.rzt.cft.dto.ResponseData;
import com.rzt.cft.dto.project.ProjectDetailDto;
import com.rzt.cft.dto.project.ProjectOrderDto;
import com.rzt.cft.dto.uc.*;
import com.rzt.cft.entity.project.ProjectDetail;
import com.rzt.cft.entity.project.ProjectOrder;
import com.rzt.cft.entity.project.ProjectStatistics;
import com.rzt.cft.entity.uc.*;
import com.rzt.cft.param.IdParam;
import com.rzt.cft.param.project.ProjectOrderPageParam;
import com.rzt.cft.param.sys.AccountLogin;
import com.rzt.cft.param.sys.RegisterUser;
import com.rzt.cft.param.uc.*;
import com.rzt.cft.service.project.IProjectDetailService;
import com.rzt.cft.service.project.IProjectOrderService;
import com.rzt.cft.service.project.IProjectStatisticsService;
import com.rzt.cft.service.uc.*;
import com.rzt.cft.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 普通用户表 前端控制器
 * </p>
 *
 * @author zhongzhong
 * @since 2020-01-10
 */
@RestController
@RequestMapping("/v1/api/user")
@Api(tags = "平台用户相关接口")
@Slf4j
public class UcUserController extends BaseController {

    @Autowired
    private IUcAccountService ucAccountService;

    @Autowired
    private IUcWalletService ucWalletService;

    @Autowired
    private IUcRechargeService ucRechargeService;

    @Autowired
    private IUcWithdrawService ucWithdrawService;

    @Autowired
    private IProjectDetailService projectDetailService;

    @Autowired
    private IProjectOrderService projectOrderService;

    @Autowired
    private IUcUsableService ucUsableService;

    @Autowired
    private IUcAssetService ucAssetService;

    @Autowired
    private IUcAssetStatisticsService ucAssetStatisticsService;

    @Autowired
    private IUcIntegralService ucIntegralService;

    @Autowired
    private IUcReceivingAddressService ucReceivingAddressService;

    @Autowired
    private IUcLogoutService ucLogoutService;

    @Autowired
    private IUcTransferService transferService;

    @Autowired
    private IProjectStatisticsService projectStatisticsService;

    @Autowired
    private IUcDistributionTypeService ucDistributionTypeService;

    @Autowired
    private IUcRebateLogService ucRebateLogService;

    @Autowired
    private IUcDistributionLogService distributionLogService;


    /**
     * 注册
     * @param registerUser
     * @return
     */
    @ApiOperation( "注册")
    @PostMapping("register")
    @CustomAuthorize(skip = true)
    public ResponseData<Boolean> register(@RequestBody RegisterUser registerUser) {

        ResponseData paramVali = ValidatorUtils.validateEntity(registerUser);
        if (Objects.nonNull(paramVali)) {
            return paramVali;
        }

        //判断验证码是否正确
//        Boolean check = cmsSmsService.checkCode(registerUser.getPhone(), registerUser.getSimplify(), registerUser.getCode());
//        Boolean check = true;
//        if (!check) {
//            return fail(ServiceStatus.MSG_ERROR);
//        }

        UcAccount ucAccount = ucAccountService.findOneByKv("account", registerUser.getAccount());
        if (Objects.nonNull(ucAccount)) {
            return fail(ServiceStatus.REPEAT_OF_ACCOUNT);
        }

        return success(ucUserService.appRegisterUser(registerUser));
    }

    /**
     * 修改密码
     * @param editPwdParam
     * @return
     */
    @ApiOperation( "修改密码")
    @PostMapping("updatePassword")
    public ResponseData<Boolean> updatePassword(@RequestBody UserEditPwdParam editPwdParam) {
        ResponseData paramVali = ValidatorUtils.validateEntity(editPwdParam);
        if (Objects.nonNull(paramVali)) {
            return paramVali;
        }
        UcAccount ucAccount = ucAccountService.findOneByKv("user_id", getUserId());
        if (Objects.isNull(ucAccount)) {
            return fail(ServiceStatus.USER_NULL);
        }

        String pw = Md5Utils.shiroMD5(ucAccount.getSalt(), editPwdParam.getOldPwd());
        if (!pw.equals(ucAccount.getPassword())) {
            return fail(ServiceStatus.ORIGINAL_PASSWORD_ERROR);
        }

        pw = Md5Utils.shiroMD5(ucAccount.getSalt(), editPwdParam.getNewPwd());
        ucAccount.setPassword(pw);
        Boolean result = ucAccountService.updateById(ucAccount);

        return success(result);
    }

//    /**
//     * 忘记密码，重置密码
//     * @param resetPwdParam
//     * @return
//     */
//    @ApiOperation( "重置密码")
//    @PostMapping("resetPassword")
//    public ResponseData<Boolean> resetPassword(@RequestBody UcResetPwdParam resetPwdParam) {
//        //校验参数
//        ResponseData paramVali = ValidatorUtils.validateEntity(resetPwdParam);
//        if (Objects.nonNull(paramVali)) {
//            return paramVali;
//        }
//       //校验验证码
////        Boolean check = cmsSmsService.checkCode(resetPwdParam.getPhone(), resetPwdParam.getSimplify(), resetPwdParam.getCode());
//        Boolean check = true;
//        if (!check) {
//            return fail(ServiceStatus.MSG_ERROR);
//        }
//        //校验手机号是否注册
//        UcUser ucUser = ucUserService.findOneByKv("phone", resetPwdParam.getPhone());
//        if (Objects.isNull(ucUser)) {
//            return fail(ServiceStatus.MOBILE_NUMBER_NOT_REGISTERED);
//        }
//
//        UcAccount ucAccount = ucAccountService.findOneByKv("user_id", ucUser.getId());
//
//        String pw = Md5Utils.shiroMD5(ucAccount.getSalt(), resetPwdParam.getNewPwd());
//        ucAccount.setPassword(pw);
//        Boolean result = ucAccountService.updateById(ucAccount);
//
//        return success(result);
//    }

    /**
     * 刷新当前登录信息
     * @return
     */
    @ApiOperation( "刷新当前登录信息")
    @PostMapping("currentUser")
    public ResponseData<UcUserDto> currentUser() {
        UcUserDto ucUserDto = getUser();
        return success(ucUserDto);
    }

    /**
     * 账号密码登录
     * @param accountLogin
     * @return
     */
    @ApiOperation( "账号密码登录")
    @PostMapping("accountLogin")
    @CustomAuthorize(skip = true)
    public ResponseData<UcLogin> accountLogin(@RequestBody AccountLogin accountLogin) {
        if (StringUtils.isBlank(accountLogin.getAccount())) {
            return fail(ServiceStatus.USER_NAMEPWDERROR);
        }
        UcAccount ucAccount = ucAccountService.findOneByKv("account", accountLogin.getAccount());
//        if (Objects.isNull(ucAccount)) {
//            UcUser ucUser = ucUserService.findOneByKv("phone", accountLogin.getAccount());
//            if (Objects.nonNull(ucUser)) {
//                ucAccount = ucAccountService.findOneByKv("user_id", ucUser.getId());
//            }
//        }
        if (Objects.isNull(ucAccount)) {
            return fail(ServiceStatus.USER_NAMEPWDERROR);
        }

        String pw = Md5Utils.shiroMD5(ucAccount.getSalt(), accountLogin.getPassword());
        if (!pw.equals(ucAccount.getPassword())) {
            return fail(ServiceStatus.USER_NAMEPWDERROR);
        }

        String token = JwtUtil.createToken(ucAccount.getUserId());
        UcLogin ucLogin = new UcLogin();
        ucLogin.setToken(token);
        ucLogin.setUcUserDto(getUser());
        return success(ucLogin);
    }

    @ApiOperation("设置头像或昵称")
    @PostMapping("/setHead")
    public ResponseData<Boolean> setHead(@RequestBody SetHeadParam para) {
        UcUser ucUser = ucUserService.getById(getUserId());
        if (StringUtils.isNotBlank(para.getNickName())) {
            ucUser.setNickName(para.getNickName());
        }
        if (StringUtils.isNotBlank(para.getHeadPortrait())) {
            ucUser.setHeadPortrait(para.getHeadPortrait());
        }
        if (para.getSex() != null && (para.getSex() == 1 || para.getSex() == 2)) {
            ucUser.setSex(para.getSex());
        }
        Boolean result = ucUserService.updateById(ucUser);
        return success(result);
    }

    @ApiOperation("我的钱包地址")
    @PostMapping("/walletList")
    public ResponseData<List<UcWalletDto>> walletList() {
        QueryWrapper<UcWallet> queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", getUserId());
        List<UcWallet> ucWallets = ucWalletService.list(queryWrapper);
        return success(CustomUtil.maping(ucWallets, UcWalletDto.class));
    }


    @ApiOperation("钱包添加")
    @PostMapping("/walletAdd")
    public ResponseData<Boolean> walletAdd(@RequestBody AddUcWallet addUcWallet) {
        UcUserDto ucUserDto = getUser();
        UcWallet ucWallet = CustomUtil.maping(addUcWallet, UcWallet.class);
        ucWallet.setUserId(ucUserDto.getId());
        ucWallet.setUserName(ucUserDto.getNickName());
        ucWallet.setPhone(ucUserDto.getPhone());
        boolean result = ucWalletService.save(ucWallet);
        return success(result);
    }

    @ApiOperation("钱包修改")
    @PostMapping("/walletUpdate")
    public ResponseData<Boolean> walletUpdate(@RequestBody AddUcWallet addUcWallet) {
        UcWallet old = ucWalletService.getById(addUcWallet.getId());
        if (Objects.isNull(old)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        UcWallet ucWallet = CustomUtil.maping(addUcWallet, UcWallet.class);
        Boolean result = ucWalletService.updateById(ucWallet);

        return success(result);
    }

    @ApiOperation("钱包删除")
    @PostMapping("/walletDelete")
    public ResponseData<Boolean> walletDelete(@RequestBody String... ids) {
        boolean result = ucWalletService.removeByIds(Arrays.asList(ids));
        return success(result);
    }

    @ApiOperation("提交充值订单")
    @PostMapping("/recharge/add")
    public ResponseData<Boolean> rechargeAdd(@RequestBody AddUcRecharge addUcRecharge) {
        UcUserDto ucUserDto = getUser();
        UcRecharge ucRecharge = CustomUtil.maping(addUcRecharge, UcRecharge.class);
        ucRecharge.setUserId(ucUserDto.getId());
        ucRecharge.setUserName(ucUserDto.getNickName());
        ucRecharge.setStatus(StatusConstant.UcRechargeStatus.WAIT_AUDITED);
        ucRecharge.setTxnSsn(CustomUtil.getSsn());
        boolean result = ucRechargeService.save(ucRecharge);
        return success(result);
    }

    @ApiOperation("我的充值订单记录")
    @PostMapping("/recharge/list")
    public ResponseData<List<UcRechargeDto>> rechargeList() {
        QueryWrapper<UcRecharge> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getUserId());
        queryWrapper.orderByDesc("create_at");
        List<UcRecharge> ucRechargeList = ucRechargeService.list(queryWrapper);
        return success(CustomUtil.maping(ucRechargeList, UcRechargeDto.class));
    }

    @ApiOperation("提交提现订单")
    @PostMapping("/withdraw/add")
    public ResponseData<Boolean> withdrawAdd(@RequestBody AddUcWithdraw addUcWithdraw) {
        UcUserDto ucUserDto = getUser();
        //校验密码
        UcAccount ucAccount = ucAccountService.findOneByKv("user_id", ucUserDto.getId());
        if (Objects.isNull(ucAccount)) {
            return fail(ServiceStatus.PWD_ERROR);
        }
        String pw = Md5Utils.shiroMD5(ucAccount.getSalt(), addUcWithdraw.getPwd());
        if (!pw.equals(ucAccount.getPassword())) {
            return fail(ServiceStatus.PWD_ERROR);
        }
        return ucWithdrawService.withdrawAdd(addUcWithdraw, ucUserDto);
    }

    @ApiOperation("我的提现订单记录")
    @PostMapping("/withdraw/list")
    public ResponseData<List<UcWithdrawDto>> withdrawList() {
        QueryWrapper<UcWithdraw> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getUserId());
        queryWrapper.orderByDesc("create_at");
        List<UcWithdraw> ucWithdrawList = ucWithdrawService.list(queryWrapper);
        return success(CustomUtil.maping(ucWithdrawList, UcWithdrawDto.class));
    }

    @ApiOperation("项目注资")
    @PostMapping("/capitalInjection")
    public ResponseData<String> capitalInjection(@RequestBody ProjectInjection projectInjection) {
        UcUserDto ucUserDto = getUser();
        //校验密码
        UcAccount ucAccount = ucAccountService.findOneByKv("user_id", ucUserDto.getId());
        if (Objects.isNull(ucAccount)) {
            return fail(ServiceStatus.PWD_ERROR);
        }
        String pw = Md5Utils.shiroMD5(ucAccount.getSalt(), projectInjection.getPwd());
        if (!pw.equals(ucAccount.getPassword())) {
            return fail(ServiceStatus.PWD_ERROR);
        }
        //校验项目是否存在
        ProjectDetail projectDetail = projectDetailService.getById(projectInjection.getId());
        if (Objects.isNull(projectDetail)) {
            return fail(ServiceStatus.PROJECT_DOES_NOT_EXIST);
        }
        //如果是自选，校验金额是否是在参数中
        if (projectDetail.getType().equals(TypeConstant.projectType.OPTIONAL)
                && !projectDetail.getSubscriptionAmount().contains(projectInjection.getAmount().toString())) {
            return fail(ServiceStatus.AMOUNT_IS_NOT_IN_THE_OPTIONAL);
        }
        //如果是智能，校验期限
        if (projectDetail.getType().equals(TypeConstant.projectType.INTELLIGENCE)) {
            if (!projectInjection.getTerm().equals(TypeConstant.projectTerm.HALF_YEAR)
                    && !projectInjection.getTerm().equals(TypeConstant.projectTerm.ONE_YEAR)){
                return fail(ServiceStatus.WRONG_TERM_SELECTION);
            }
        }
        //校验是否有退出记录
        List<String> statusList = new ArrayList<>();
        statusList.add(StatusConstant.UcRechargeStatus.ADOPT);
        statusList.add(StatusConstant.UcRechargeStatus.WAIT_AUDITED);
        QueryWrapper<UcLogout> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", ucUserDto.getId());
        queryWrapper.eq("status", statusList);
        if(projectDetail.getType().equals(TypeConstant.projectType.OPTIONAL)) {
            queryWrapper.eq("project_type", TypeConstant.projectType.OPTIONAL);
        }
        if(projectDetail.getType().equals(TypeConstant.projectType.INTELLIGENCE)) {
            queryWrapper.eq("project_type", TypeConstant.projectType.INTELLIGENCE);
        }
        List<UcLogout> ucLogouts = ucLogoutService.list(queryWrapper);
        if (ucLogouts.size() > 0) {
            return fail(ServiceStatus.HAS_BEEN_APPLIED_FOR_AND_CAPITAL_INJECTION);
        }
        return projectDetailService.capitalInjection(projectInjection, ucUserDto, projectDetail);
    }

    @ApiOperation("我的注资订单")
    @PostMapping("/capitalInjection/list")
    public ResponseData<IPage<ProjectOrderDto>> capitalInjectionList(@RequestBody ProjectOrderPageParam param) {
        Page page = getPage(param);
        QueryWrapper<ProjectOrder> queryWrapper =  ParseWrapper.parseWrapper(param);
        queryWrapper.eq("user_id", getUserId());
        queryWrapper.orderByDesc("create_at");
        IPage<ProjectOrder> orderIPage = projectOrderService.page(page, queryWrapper);
        return success(orderIPage.convert(x -> CustomUtil.maping(x, ProjectOrderDto.class)));
    }

    @ApiOperation("项目详情")
    @PostMapping("/project/detail")
    public ResponseData<ProjectDetailDto> projectDetail(@RequestBody IdParam param) {
        ProjectDetail projectDetail = projectDetailService.getById(param.getId());
        if (Objects.isNull(projectDetail)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        ProjectDetailDto projectDetailDto = CustomUtil.maping(projectDetail, ProjectDetailDto.class);
        QueryWrapper<ProjectStatistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id", projectDetail.getId());
        queryWrapper.eq("current", true);
        ProjectStatistics projectStatistics = projectStatisticsService.getOne(queryWrapper);
        if (Objects.nonNull(projectStatistics)) {
            projectDetailDto.setSurplus(projectStatistics.getSurplus());
            projectDetailDto.setRealProgress(projectStatistics.getRealProgress());
            projectDetailDto.setVirtualProgress(projectStatistics.getVirtualProgress());
        }

        return success(projectDetailDto);
    }

    @ApiOperation("我的资金记录")
    @PostMapping("/usable/list")
    public ResponseData<IPage<UcUsableDto>> usableList(@RequestBody UsableParam param) {
        Page page = getPage(param);
        QueryWrapper<UcUsable> queryWrapper =  ParseWrapper.parseWrapper(param);
        queryWrapper.eq("user_id", getUserId());
        queryWrapper.orderByDesc("create_at");
        IPage<UcUsable> ucUsableIPage = ucUsableService.page(page, queryWrapper);
        List<String> orderIds = CustomUtil.select(ucUsableIPage.getRecords(), UcUsable::getRemarks);
        IPage<UcUsableDto> ucUsableDtoIPage = ucUsableIPage.convert(x -> CustomUtil.maping(x, UcUsableDto.class));
        if (orderIds.size() == 0) {
            return success(ucUsableDtoIPage);
        }
        List<ProjectOrder> projectOrders = projectOrderService.listByIds(orderIds);
        if (projectOrders.size() == 0) {
            return success(ucUsableDtoIPage);
        }
        ucUsableDtoIPage.getRecords().forEach(x -> {
            if (StringUtils.isNotBlank(x.getRemarks())) {
                ProjectOrder projectOrder = CustomUtil.first(projectOrders, m -> x.getRemarks().equals(m.getId()));
                if (Objects.nonNull(projectOrder)) {
                    x.setProjectType(projectOrder.getProjectType());
                    x.setProjectName(projectOrder.getProjectName());
                }
            }
        });
        return success(ucUsableDtoIPage);
    }

    @ApiOperation("我的积分记录")
    @PostMapping("/integral/list")
    public ResponseData<IPage<UcIntegralDto>> integralList(@RequestBody UsableParam param) {
        Page page = getPage(param);
        List<String> typeList = new ArrayList<>();
        typeList.add(TypeConstant.integralChangeType.INTEGRAL_PROJECT_REBATE);
        typeList.add(TypeConstant.integralChangeType.INTEGRAL_PROJECT_EXIT);
        QueryWrapper<UcIntegral> queryWrapper =  ParseWrapper.parseWrapper(param);
        queryWrapper.eq("user_id", getUserId());
        queryWrapper.notIn("type", typeList);
        queryWrapper.orderByDesc("create_at");
        IPage<UcIntegral> ucIntegralIPage = ucIntegralService.page(page, queryWrapper);
        List<String> orderIds = CustomUtil.select(ucIntegralIPage.getRecords(), UcIntegral::getRemarks);
        IPage<UcIntegralDto> ucIntegralDtoIPage = ucIntegralIPage.convert(x -> CustomUtil.maping(x, UcIntegralDto.class));
        if (orderIds.size() == 0) {
            return success(ucIntegralDtoIPage);
        }
        List<ProjectOrder> projectOrders = projectOrderService.listByIds(orderIds);
        if (projectOrders.size() == 0) {
            return success(ucIntegralDtoIPage);
        }
        ucIntegralDtoIPage.getRecords().forEach(x -> {
            if (StringUtils.isNotBlank(x.getRemarks())) {
                ProjectOrder projectOrder = CustomUtil.first(projectOrders, m -> x.getRemarks().equals(m.getId()));
                if (Objects.nonNull(projectOrder)) {
                    x.setProjectType(projectOrder.getProjectType());
                }
            }
        });
        return success(ucIntegralDtoIPage);
    }

    @ApiOperation("注资订单详情")
    @PostMapping("/projectOrder/detail")
    public ResponseData<ProjectOrderDto> projectOrderDetail(@RequestBody IdParam param) {
        ProjectOrder projectOrder = projectOrderService.getById(param.getId());
        if (Objects.isNull(projectOrder)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        return success(CustomUtil.maping(projectOrder, ProjectOrderDto.class));
    }

    @ApiOperation("充值订单详情")
    @PostMapping("/recharge/detail")
    public ResponseData<UcRechargeDto> rechargeDetail(@RequestBody IdParam param) {
        UcRecharge ucRecharge = ucRechargeService.getById(param.getId());
        if (Objects.isNull(ucRecharge)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        return success(CustomUtil.maping(ucRecharge, UcRechargeDto.class));
    }

    @ApiOperation("提现订单详情")
    @PostMapping("/withdraw/detail")
    public ResponseData<UcWithdrawDto> withdrawDetail(@RequestBody IdParam param) {
        UcWithdraw ucWithdraw = ucWithdrawService.getById(param.getId());
        if (Objects.isNull(ucWithdraw)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        return success(CustomUtil.maping(ucWithdraw, UcWithdrawDto.class));
    }

    @ApiOperation("个人信息")
    @PostMapping("/detail")
    public ResponseData<UcUserDetailDto> detail() {
        UcUser ucUser = ucUserService.getById(getUserId());
        UcUserDetailDto ucUserDetailDto = CustomUtil.maping(ucUser, UcUserDetailDto.class);
        QueryWrapper queryWrapper =  new QueryWrapper<>();
        queryWrapper.eq("current", true);
        queryWrapper.eq("user_id", ucUser.getId());
        UcAsset ucAsset = ucAssetService.getOne(queryWrapper);
        if (Objects.nonNull(ucAsset)) {
            ucUserDetailDto.setInvestment(ucAsset.getInvestment());
            ucUserDetailDto.setUsable(ucAsset.getUsable());
            ucUserDetailDto.setIntegral(ucAsset.getIntegral());
        }
        UcAssetStatistics ucAssetStatistics = ucAssetStatisticsService.getOne(queryWrapper);
        if (Objects.nonNull(ucAssetStatistics)) {
            ucUserDetailDto.setAccumulationIntegral(ucAssetStatistics.getAccumulationIntegral());
            ucUserDetailDto.setAccumulationInjection(ucAssetStatistics.getAccumulationInjection());
            ucUserDetailDto.setAccumulationRebate(ucAssetStatistics.getAccumulationRebate());
        }

        UcDistributionType distributionType = ucDistributionTypeService.getById(ucUser.getDistributionId());
        if (Objects.nonNull(distributionType)) {
            ucUserDetailDto.setIcon(distributionType.getIcon());
            ucUserDetailDto.setDistributionName(distributionType.getName());
        }
        return success(ucUserDetailDto);
    }

    @ApiOperation("我的收货地址")
    @PostMapping("/receivingAddressList")
    public ResponseData<List<UcReceivingAddressDto>> receivingAddressList() {
        QueryWrapper<UcReceivingAddress> queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", getUserId());
        List<UcReceivingAddress> ucReceivingAddresses = ucReceivingAddressService.list(queryWrapper);
        return success(CustomUtil.maping(ucReceivingAddresses, UcReceivingAddressDto.class));
    }

    @ApiOperation("收货地址添加")
    @PostMapping("/receivingAddressAdd")
    public ResponseData<Boolean> receivingAddressAdd(@RequestBody AddUcReceivingAddress addUcReceivingAddress) {
        UcUserDto ucUserDto = getUser();
        UcReceivingAddress receivingAddress = CustomUtil.maping(addUcReceivingAddress, UcReceivingAddress.class);
        receivingAddress.setUserId(ucUserDto.getId());
        receivingAddress.setCode(ucUserDto.getCode());
        boolean result = ucReceivingAddressService.save(receivingAddress);
        return success(result);
    }

    @ApiOperation("收货地址修改")
    @PostMapping("/receivingAddressUpdate")
    public ResponseData<Boolean> receivingAddresstUpdate(@RequestBody AddUcReceivingAddress addUcReceivingAddress) {
        UcReceivingAddress old = ucReceivingAddressService.getById(addUcReceivingAddress.getId());
        if (Objects.isNull(old)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        UcReceivingAddress ucReceivingAddress = CustomUtil.maping(addUcReceivingAddress, UcReceivingAddress.class);
        Boolean result = ucReceivingAddressService.updateById(ucReceivingAddress);

        return success(result);
    }

    @ApiOperation("收货地址删除")
    @PostMapping("/receivingAddressDelete")
    public ResponseData<Boolean> receivingAddressDelete(@RequestBody String... ids) {
        boolean result = ucReceivingAddressService.removeByIds(Arrays.asList(ids));
        return success(result);
    }

    @ApiOperation("退出申请")
    @PostMapping("/logout/add")
    public ResponseData<Boolean> logoutAdd(@RequestBody AddUcLogout addUcLogout) {
        UcUserDto ucUserDto = getUser();
        if (!addUcLogout.getProjectType().equals(TypeConstant.projectType.INTELLIGENCE) &&
                !addUcLogout.getProjectType().equals(TypeConstant.projectType.OPTIONAL)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }

        //如果是智能有产品未满60天，不能退
        if(addUcLogout.getProjectType().equals(TypeConstant.projectType.INTELLIGENCE)) {
            LocalDateTime before = LocalDateTime.now().plusDays(-60);
            QueryWrapper<ProjectOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", ucUserDto.getId());
            queryWrapper.eq("project_type", TypeConstant.projectType.INTELLIGENCE);
            queryWrapper.eq("status", StatusConstant.ProjectOrderStatus.IN_HAND);
            queryWrapper.ge("injection_time", before);
            List<ProjectOrder> projectOrderList = projectOrderService.list(queryWrapper);
            if (projectOrderList.size() > 0) {
                return fail(ServiceStatus.PRODUCTS_WITH_LESS_THAN_60_DAYS);
            }
        }

        List<String> statusList = new ArrayList<>();
        statusList.add(StatusConstant.UcRechargeStatus.WAIT_AUDITED);
        statusList.add(StatusConstant.UcRechargeStatus.ADOPT);
        QueryWrapper<UcLogout> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", ucUserDto.getId());
        queryWrapper.eq("project_type", addUcLogout.getProjectType());
        queryWrapper.in("status", statusList);
        List<UcLogout> ucLogouts = ucLogoutService.list(queryWrapper);
        if (ucLogouts.size() > 0) {
            return fail(ServiceStatus.ALREADY_APPLIED_TO_EXIT);
        }
        Boolean result = ucLogoutService.logoutAdd(addUcLogout,ucUserDto);
        return success(result);
    }

    @ApiOperation("退出申请列表")
    @PostMapping("/logout/list")
    public ResponseData<List<UcLogoutDto>> logoutList() {
        UcUserDto ucUserDto = getUser();
        QueryWrapper<UcLogout> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", ucUserDto.getId());
        List<UcLogout> ucLogouts = ucLogoutService.list(queryWrapper);
        return success(CustomUtil.maping(ucLogouts, UcLogoutDto.class));
    }

    @ApiOperation("根据日期筛选我的收益")
    @PostMapping("/screenProfit")
    public ResponseData<BigDecimal> screenProfit(@RequestBody ScreenDateParam param) {
        UcUserDto ucUserDto = getUser();
        if (param.getStart() == null || param.getEnd() == null) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        List<String> types = new ArrayList<>();
        types.add(TypeConstant.usableChangeType.BALANCE_PROJECT_REBATE);
        types.add(TypeConstant.usableChangeType.BALANCE_DISTRIBUTION_REBATE);
        QueryWrapper<UcUsable> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", ucUserDto.getId());
        queryWrapper.ge("create_at", LocalDateTime.of(param.getStart(), LocalTime.MIN));
        queryWrapper.le("create_at", LocalDateTime.of(param.getEnd(), LocalTime.MAX));
        queryWrapper.in("type", types);
        BigDecimal profit = BigDecimal.ZERO;
        List<UcUsable> ucUsableList = ucUsableService.list(queryWrapper);
        for(UcUsable ucUsable : ucUsableList) {
            profit = profit.add(ucUsable.getChangeAmount());
        }
        return success(profit);
    }

    @ApiOperation("我的推荐人和我的伞下")
    @PostMapping("/childList")
    public ResponseData<UcRecommenderChildDto> childList() {
        UcUserDto ucUserDto = getUser();
        UcRecommenderChildDto ucRecommenderChildDto = new UcRecommenderChildDto();
        if (StringUtils.isNotBlank(ucUserDto.getParentId())) {
            UcUser ucUser = ucUserService.getById(ucUserDto.getParentId());
            UcChildDto recommenderDto = CustomUtil.maping(ucUser, UcChildDto.class);
            QueryWrapper<UcAssetStatistics> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", recommenderDto.getId());
            queryWrapper.eq("current", true);
            UcAssetStatistics recommenderStatistics = ucAssetStatisticsService.getOne(queryWrapper);
            if (Objects.nonNull(recommenderStatistics)) {
                recommenderDto.setAccumulationIntegral(recommenderStatistics.getAccumulationIntegral());
                recommenderDto.setAccumulationRebate(recommenderStatistics.getAccumulationRebate());
            }
            ucRecommenderChildDto.setRecommenderDto(recommenderDto);
        }
        QueryWrapper<UcUser> ucUserQueryWrapper = new QueryWrapper<>();
        ucUserQueryWrapper.eq("parent_id", ucUserDto.getId());
        List<UcUser> ucUserList = ucUserService.list(ucUserQueryWrapper);
        List<UcChildDto> ucChildDtos = CustomUtil.maping(ucUserList, UcChildDto.class);
        if (ucUserList.size() > 0) {
            List<String> ids = CustomUtil.select(ucUserList, UcUser::getId);
            QueryWrapper<UcAssetStatistics> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("user_id", ids);
            queryWrapper.eq("current", true);
            List<UcAssetStatistics> ucAssetStatisticList = ucAssetStatisticsService.list(queryWrapper);
            ucChildDtos.forEach(x -> {
                UcAssetStatistics ucAssetStatistics = CustomUtil.first(ucAssetStatisticList, m -> x.getId().equals(m.getUserId()));
                if (Objects.nonNull(ucAssetStatistics)) {
                    x.setAccumulationRebate(ucAssetStatistics.getAccumulationRebate());
                    x.setAccumulationIntegral(ucAssetStatistics.getAccumulationIntegral());
                }
            });
        }
        ucRecommenderChildDto.setChildDto(ucChildDtos);
        return success(ucRecommenderChildDto);
    }

    @ApiOperation("我的伞下总人数")
    @PostMapping("/childCount")
    public ResponseData<Integer> childCount() {
        List<UcUser> ucUserList = new ArrayList<>();
        List<String> idList = new ArrayList<>();
        idList.add(getUserId());
        ucUserList = ucRebateLogService.childList(ucUserList, idList);
        return success(ucUserList.size());
    }


    @ApiOperation("绑定邀请人")
    @PostMapping("/bindInvitees")
    public ResponseData<Boolean> bindInvitees(@RequestBody InviteesParam param) {
        UcUserDto ucUserDto = getUser();
        if (StringUtils.isNotBlank(ucUserDto.getParentId())) {
            return fail(ServiceStatus.YOU_HAVE_BOUND_THE_INVITEE);
        }
        if (param.getParentCode().equals(ucUserDto.getCode())) {
            return fail(ServiceStatus.CAN_NOT_BIND_YOURSELF_INVITING);
        }
        QueryWrapper<UcUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", param.getParentCode());
        UcUser parentUser = ucUserService.getOne(queryWrapper);
        if (Objects.isNull(parentUser)) {
            fail(ServiceStatus.NO_USERS_FOUND_FOR_ODE);
        }
        UcUser ucUser = new UcUser();
        ucUser.setId(ucUserDto.getId());
        ucUser.setParentId(parentUser.getId());
        ucUser.setParentCode(parentUser.getCode());
        Boolean result = ucUserService.updateById(ucUser);
        return success(result);
    }

    @ApiOperation("转账")
    @PostMapping("/transfer/add")
    public ResponseData<Boolean> transferAdd(@RequestBody AddTransferParam param) {
        UcUserDto ucUserDto = getUser();
        //校验密码
        UcAccount ucAccount = ucAccountService.findOneByKv("user_id", ucUserDto.getId());
        if (Objects.isNull(ucAccount)) {
            return fail(ServiceStatus.PWD_ERROR);
        }
        String pw = Md5Utils.shiroMD5(ucAccount.getSalt(), param.getPwd());
        if (!pw.equals(ucAccount.getPassword())) {
            return fail(ServiceStatus.PWD_ERROR);
        }

        //校验关系
        QueryWrapper<UcUser> ucUserQueryWrapper = new QueryWrapper<>();
        ucUserQueryWrapper.eq("parent_id", ucUserDto.getId());
        List<UcUser> ucUserList = ucUserService.list(ucUserQueryWrapper);
        List<String> ids = CustomUtil.select(ucUserList, UcUser::getId);
        if (!param.getInUserId().equals(ucUserDto.getParentId()) && !ids.contains(param.getInUserId())) {
            return fail(ServiceStatus.UNABLE_TO_TRANSFER_ACCOUNTS);
        }
        //校验金额和积分
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", ucUserDto.getId());
        queryWrapper.eq("current", true);
        UcUsable ucUsable = ucUsableService.getOne(queryWrapper);

        queryWrapper.eq("user_id", ucUserDto.getId());
        queryWrapper.eq("current", true);
        UcIntegral ucIntegral = ucIntegralService.getOne(queryWrapper);
        if (param.getAmt() != null && ucUsable != null && ucUsable.getUsable().compareTo(param.getAmt()) < 0) {
            return fail(ServiceStatus.YOUR_CREDIT_RUNNING_LOW);
        }
        if (param.getIntegral() != null && ucIntegral != null && ucIntegral.getIntegral().compareTo(param.getIntegral()) < 0) {
            return fail(ServiceStatus.INTEGRAL_EFICIENCY);
        }
        Boolean result = transferService.transfer(ucUserDto, param);
        return success(result);
    }

    @ApiOperation("资金记录详情")
    @PostMapping("/usable/detail")
    public ResponseData<UcUsableDetailDto> usableDetail(@RequestBody IdParam param) {
        UcUsable ucUsable = ucUsableService.getById(param.getId());
        if (Objects.isNull(ucUsable)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        UcUsableDetailDto ucUsableDetailDto = CustomUtil.maping(ucUsable, UcUsableDetailDto.class);
        if (ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_CAPITAL_INJECTION)) {
            ProjectOrder projectOrder = projectOrderService.getById(ucUsable.getRemarks());
            if (Objects.nonNull(projectOrder)) {
                ucUsableDetailDto.setInjectionTime(projectOrder.getInjectionTime());
                ucUsableDetailDto.setProjectName(projectOrder.getProjectName());
                ucUsableDetailDto.setProjectType(projectOrder.getProjectType());
            }
        }

        if (ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_RETUR_CAPITAL)
                || ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_PROJECT_REBATE)
                || ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_DISTRIBUTION_REBATE)) {
            UcRebateLog ucRebateLog = ucRebateLogService.getById(ucUsable.getRemarks());
            ucUsableDetailDto.setIntegral(ucRebateLog.getIntegral());
            ProjectOrder projectOrder = projectOrderService.getById(ucRebateLog.getProjectOrderId());
            if (Objects.nonNull(projectOrder)) {
                ucUsableDetailDto.setInjectionTime(projectOrder.getInjectionTime());
                ucUsableDetailDto.setProjectName(projectOrder.getProjectName());
                ucUsableDetailDto.setProjectType(projectOrder.getProjectType());
                ucUsableDetailDto.setInvestmentAmount(projectOrder.getAmount());
            }

            if (ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_DISTRIBUTION_REBATE)) {
                QueryWrapper<UcIntegral> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("remarks", ucUsable.getRemarks());
                UcIntegral ucIntegral = ucIntegralService.getOne(queryWrapper);
                if (Objects.nonNull(ucIntegral)) {
                    ucUsableDetailDto.setIntegral(ucIntegral.getChangeIntegral());
                }
                UcUser ucUser = ucUserService.getById(projectOrder.getUserId());
                if (Objects.nonNull(ucRebateLog)) {
                    ucUsableDetailDto.setChildAccount(ucUser.getAccount());
                    ucUsableDetailDto.setChildCode(ucUser.getCode());
                    ucUsableDetailDto.setChildNickName(ucUser.getNickName());
                    ucUsableDetailDto.setChildUserId(ucUser.getId());
                }
            }
        }

        if (ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_RETUR_CAPITAL)) {
            QueryWrapper<UcIntegral> integralQueryWrapper = new QueryWrapper<>();
            integralQueryWrapper.eq("remarks", ucUsable.getRemarks());
            List<UcIntegral> ucIntegralList = ucIntegralService.list(integralQueryWrapper);
            if (ucIntegralList.size() > 0) {
                ucUsableDetailDto.setIntegral(ucIntegralList.get(0).getIntegral());
            }
        }

        if (ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_RECHARGE)) {
            UcRecharge ucRecharge = ucRechargeService.getById(ucUsable.getRemarks());
            if (Objects.nonNull(ucRecharge)) {
                ucUsableDetailDto.setPicture(ucRecharge.getPicture());
            }
        }

        if (ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_PROJECT_EXIT)) {
            UcLogout ucLogout = ucLogoutService.getById(ucUsable.getRemarks());
            if (Objects.nonNull(ucLogout)) {
                ucUsableDetailDto.setInvestmentAmount(ucLogout.getAmount());
                ucUsableDetailDto.setIntegral(ucLogout.getAmount().multiply(new BigDecimal(0.4)));
            }
        }

        if (ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_WITHDRAW)) {
            UcWithdraw ucWithdraw = ucWithdrawService.getById(ucUsable.getRemarks());
            if (Objects.nonNull(ucWithdraw)) {
                ucUsableDetailDto.setWalletUrl(ucWithdraw.getWalletUrl());
            }
        }

        if (ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_TURN_OUT)) {
            UcTransfer ucTransfer = transferService.getById(ucUsable.getRemarks());
            UcUser ucUser = ucUserService.getById(ucTransfer.getInUserId());
            if (Objects.nonNull(ucTransfer)) {
                ucUsableDetailDto.setInUserCode(ucUser.getCode());
            }
        }

        if (ucUsable.getType().equals(TypeConstant.usableChangeType.BALANCE_TURN_IN)) {
            UcTransfer ucTransfer = transferService.getById(ucUsable.getRemarks());
            UcUser ucUser = ucUserService.getById(ucTransfer.getOutUserId());
            if (Objects.nonNull(ucTransfer)) {
                ucUsableDetailDto.setOutUserCode(ucUser.getCode());
            }
        }
        return success(ucUsableDetailDto);
    }

    @ApiOperation("积分记录详情")
    @PostMapping("/integral/detail")
    public ResponseData<UcIntegralDetailDto> integralDetail(@RequestBody IdParam param) {
        UcIntegral ucIntegral = ucIntegralService.getById(param.getId());
        if (Objects.isNull(ucIntegral)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        UcIntegralDetailDto ucIntegralDetailDto = CustomUtil.maping(ucIntegral, UcIntegralDetailDto.class);

        if (ucIntegral.getType().equals(TypeConstant.integralChangeType.INTEGRAL_PROJECT_REBATE)) {
            ProjectOrder projectOrder = projectOrderService.getById(ucIntegral.getRemarks());
            if (Objects.nonNull(projectOrder)) {
                ucIntegralDetailDto.setInvestmentAmount(projectOrder.getAmount());
            }
        }

        if (ucIntegral.getType().equals(TypeConstant.integralChangeType.INTEGRAL_PROJECT_EXIT)) {
            UcLogout ucLogout = ucLogoutService.getById(ucIntegral.getRemarks());
            if (Objects.nonNull(ucLogout)) {
                ucIntegralDetailDto.setInvestmentAmount(ucLogout.getAmount());
            }
        }

        if (ucIntegral.getType().equals(TypeConstant.integralChangeType.INTEGRAL_DISTRIBUTION_REBATE)) {
            UcRebateLog ucRebateLog = ucRebateLogService.getById(ucIntegral.getRemarks());
            ProjectOrder projectOrder = projectOrderService.getById(ucRebateLog.getProjectOrderId());
            ucIntegralDetailDto.setProjectName(projectOrder.getProjectName());
            ucIntegralDetailDto.setProjectType(projectOrder.getProjectType());
            UcUser ucUser = ucUserService.getById(projectOrder.getUserId());
            if (Objects.nonNull(ucRebateLog)) {
                ucIntegralDetailDto.setChildAccount(ucUser.getAccount());
                ucIntegralDetailDto.setChildCode(ucUser.getCode());
                ucIntegralDetailDto.setChildNickName(ucUser.getNickName());
                ucIntegralDetailDto.setChildUserId(ucUser.getId());
            }
        }

        if (ucIntegral.getType().equals(TypeConstant.usableChangeType.BALANCE_TURN_OUT)) {
            UcTransfer ucTransfer = transferService.getById(ucIntegral.getRemarks());
            UcUser ucUser = ucUserService.getById(ucTransfer.getInUserId());
            if (Objects.nonNull(ucTransfer)) {
                ucIntegralDetailDto.setInUserCode(ucUser.getCode());
            }
        }

        if (ucIntegral.getType().equals(TypeConstant.usableChangeType.BALANCE_TURN_IN)) {
            UcTransfer ucTransfer = transferService.getById(ucIntegral.getRemarks());
            UcUser ucUser = ucUserService.getById(ucTransfer.getOutUserId());
            if (Objects.nonNull(ucTransfer)) {
                ucIntegralDetailDto.setOutUserCode(ucUser.getCode());
            }
        }

        return success(ucIntegralDetailDto);
    }

    @ApiOperation("分销佣金详情(伞下用户id)")
    @PostMapping("/distribution/byDirect")
    public ResponseData<UcCommissionDetailDto> byDirect(@RequestBody IdParam param) {
        UcUser ucUser = ucUserService.getById(param.getId());
        if (Objects.isNull(ucUser)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        QueryWrapper<UcDistributionLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("direct_selling_id", param.getId());
        queryWrapper.eq("distribution_type", TypeConstant.distributionLevelType.ONE);
        List<UcDistributionLog> ucDistributionLogList = distributionLogService.list(queryWrapper);
        List<UcDistributionLogDto> distributionLogDtoList = CustomUtil.maping(ucDistributionLogList, UcDistributionLogDto.class);
        UcCommissionDetailDto ucCommissionDetailDto = new UcCommissionDetailDto();
        ucCommissionDetailDto.setDistributorCode(ucUser.getCode());
        ucCommissionDetailDto.setDistributorName(StringUtils.isBlank(ucUser.getNickName()) ? ucUser.getAccount() : ucUser.getNickName());
        BigDecimal totalIntegral = BigDecimal.ZERO;
        BigDecimal totalAmt = BigDecimal.ZERO;
        for(UcDistributionLog distributionLog: ucDistributionLogList) {
            totalIntegral = totalIntegral.add(distributionLog.getIntegral());
            totalAmt = totalAmt.add(distributionLog.getAmt());
        }
        ucCommissionDetailDto.setDistributionLogDtoList(distributionLogDtoList);
        ucCommissionDetailDto.setTotalAmt(totalAmt);
        ucCommissionDetailDto.setTotalIntegral(totalIntegral);
        return success(ucCommissionDetailDto);
    }

    @ApiOperation("会员等级列表")
    @PostMapping("/distribution/list")
    @CustomAuthorize(skip = true)
    public ResponseData<List<UcDistributionTypeDto>> list() {
        List<UcDistributionType> ucDistributionTypes = ucDistributionTypeService.list();
        return success(CustomUtil.maping(ucDistributionTypes, UcDistributionTypeDto.class));
    }

    @ApiOperation("测试")
    @PostMapping("/distribution/test")
    @CustomAuthorize(skip = true)
    public ResponseData distributiontest(@RequestBody String id) {
        //校验是否可以升级
        UpgradeParam upgradeParam = new UpgradeParam();
        upgradeParam.setId(id);
        upgradeParam.setNum(0);
        ucUserService.numUpgrade(upgradeParam);
        return null;
    }

}
